package com.ruike.alisurface.utils;

import android.os.Handler;
import android.os.Looper;

import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;

public class ThreadUtils {
    //线程池核心线程数
    private static int CORE_POOL_SIZE = 5;
    //线程池最大线程数
    private static int MAX_POOL_SIZE = 100;
    //额外线程空状态生存时间
    private static int KEEP_ALIVE_TIME = 30;
    //阻塞队列。当核心线程都被占用，且阻塞队列已满的情况下，才会开启额外线程。
    private static BlockingQueue<Runnable> workQueue = new ArrayBlockingQueue<>(10);
    //线程池
    private static ThreadPoolExecutor threadPool;
    //异步线程池
    private static ScheduledThreadPoolExecutor scheduledThreadPoolExecutor;
    //UI handler
    private static Handler handlerUI;

    private ThreadUtils() {
    }

    //线程工厂
    private static ThreadFactory threadFactory = new ThreadFactory() {
        private final AtomicInteger integer = new AtomicInteger();

        @Override
        public Thread newThread(Runnable r) {
            return new Thread(r, "thread_pool_fitness_" + integer.getAndIncrement());
        }
    };

    /**
     * corePoolSize: 线程池的核心线程数，默认情况下， 核心线程会在线程池中一直存活， 即使处于闲置状态.
     * 但如果将allowCoreThreadTimeOut设置为true的话, 那么核心线程也会有超时机制， 在keepAliveTime设置的时间过后， 核心线程也会被终止.
     * maximumPoolSize: 最大的线程数， 包括核心线程， 也包括非核心线程， 在线程数达到这个值后，新来的任务将会被阻塞.
     * keepAliveTime: 超时的时间， 闲置的非核心线程超过这个时长，讲会被销毁回收， 当allowCoreThreadTimeOut为true时，这个值也作用于核心线程.
     * unit：超时时间的时间单位.
     * workQueue：线程池的任务队列， 通过execute方法提交的runnable对象会存储在这个队列中.
     * threadFactory: 线程工厂, 为线程池提供创建新线程的功能.
     * <p>
     * <p>
     * <p>
     * handler: 任务无法执行时，回调handler的rejectedExecution方法来通知调用者.
     */
    private synchronized static void initThreadPoolIfNecessary() {
        if (threadPool == null) {
            threadPool = new ThreadPoolExecutor(CORE_POOL_SIZE, MAX_POOL_SIZE, KEEP_ALIVE_TIME,
                    TimeUnit.SECONDS, workQueue, threadFactory);
        }
    }

    /**
     * ScheduledThreadPoolExecutor
     * 核心线程数是固定的，非核心线程数量没有限制， 没有超时机制.
     * 主要用于执行定时任务和具有固定周期的重复任务.
     */
    private synchronized static void initScheduledThreadPoolIfNecessary() {
        if (scheduledThreadPoolExecutor == null) {
            scheduledThreadPoolExecutor = new ScheduledThreadPoolExecutor(CORE_POOL_SIZE, threadFactory);
        }
    }

    private synchronized static void initUIHandlerIfNecessary() {
        if (handlerUI == null) {
            handlerUI = new Handler(Looper.getMainLooper());
        }
    }

    public static void post(Runnable runnable) {
        initThreadPoolIfNecessary();
        threadPool.execute(runnable);
    }

    /**
     * 延迟执行一次
     *
     * @param runnable
     * @param timeMiles
     */
    public static void postDelayed(Runnable runnable, long timeMiles) {
        initScheduledThreadPoolIfNecessary();
        scheduledThreadPoolExecutor.schedule(runnable, timeMiles, TimeUnit.MILLISECONDS);
    }

    /**
     * 周期性执行任务
     *
     * @param runnable
     * @param initialDelay
     * @param period
     */
    public static void postDelayed(Runnable runnable, long initialDelay, long period) {
        initScheduledThreadPoolIfNecessary();
        scheduledThreadPoolExecutor.scheduleWithFixedDelay(runnable, initialDelay, period, TimeUnit.SECONDS);

    }

    public static void postUI(Runnable runnable) {
        initUIHandlerIfNecessary();
        handlerUI.post(runnable);
    }

    public static void postUIDelayed(Runnable runnable, long timeMiles) {
        initUIHandlerIfNecessary();
        handlerUI.postDelayed(runnable, timeMiles);
    }

    public static void removeCallbacks(Runnable runnable ) {
        initUIHandlerIfNecessary();
        handlerUI.removeCallbacks(runnable);

    }

}
